/** @file               sw_debug.h
 *  @copyright          Copyright (C) 2006-2026 flyfish (tenggui_fu@126.com)
 *  @brief              This file is part of the swallow library
 *  @author             $Author: Thinkpad $
 *  @version            $Rev: 427 $
 *  @date               $Date: 2017-01-24 16:55:01 +0800 (周二, 24 1月 2017) $
 */
#ifndef __SW_DEBUG_H__
#define __SW_DEBUG_H__

#ifdef __cplusplus
extern "C" {
#endif

#define SW_ANSI_STYLE_RESET             "\x1B[0m"
#define SW_ANSI_STYLE_BRIGHT            "\x1B[1m"
#define SW_ANSI_STYLE_DIM               "\x1B[2m"
#define SW_ANSI_STYLE_UNDERSCORE        "\x1B[4m"
#define SW_ANSI_STYLE_BLINK             "\x1B[5m"
#define SW_ANSI_STYLE_REVERSE           "\x1B[7m"
#define SW_ANSI_STYLE_HIDDEN            "\x1B[8m"
#define SW_ANSI_FORE_COLOR_BLACK        "\x1B[30m"
#define SW_ANSI_FORE_COLOR_RED          "\x1B[31m"
#define SW_ANSI_FORE_COLOR_GREEN        "\x1B[32m"
#define SW_ANSI_FORE_COLOR_YELLOW       "\x1B[33m"
#define SW_ANSI_FORE_COLOR_BLUE         "\x1B[34m"
#define SW_ANSI_FORE_COLOR_MAGENTA      "\x1B[35m"
#define SW_ANSI_FORE_COLOR_CYAN         "\x1B[36m"
#define SW_ANSI_FORE_COLOR_WHITE        "\x1B[37m"
#define SW_ANSI_BACK_COLOR_BLACK        "\x1B[40m"
#define SW_ANSI_BACK_COLOR_RED          "\x1B[41m"
#define SW_ANSI_BACK_COLOR_GREEN        "\x1B[42m"
#define SW_ANSI_BACK_COLOR_YELLOW       "\x1B[43m"
#define SW_ANSI_BACK_COLOR_BLUE         "\x1B[44m"
#define SW_ANSI_BACK_COLOR_MAGENTA      "\x1B[45m"
#define SW_ANSI_BACK_COLOR_CYAN         "\x1B[46m"
#define SW_ANSI_BACK_COLOR_WHITE        "\x1B[47m"

typedef enum _SW_DEBUG_STYLE
{
    SW_DS_DEFAULT,
    SW_DS_RESET,
    SW_DS_BRIGHT,
    SW_DS_DIM,
    SW_DS_UNDERSCORE,
    SW_DS_BLINK,
    SW_DS_REVERSE,
    SW_DS_HIDDEN
}SW_DEBUG_STYLE;

typedef enum _SW_DEBUG_COLOR
{
    SW_DC_DEFAULT,
    SW_DC_BLACK,
    SW_DC_RED,
    SW_DC_GREEN,
    SW_DC_YELLOW,
    SW_DC_BLUE,
    SW_DC_MAGENTA,
    SW_DC_CYAN,
    SW_DC_WHITE
}SW_DEBUG_COLOR;

typedef enum _SW_DEBUG_LEVEL
{
    SW_DL_NONE,
    SW_DL_ERR,
    SW_DL_WRN,
    SW_DL_INF,
    SW_DL_DBG,
    SW_DL_DEV,
    SW_DL_NUM
}SW_DEBUG_LEVEL;

typedef enum _SW_DEBUG_MODE
{
    SW_DM_TERM,
    SW_DM_FILE,
    SW_DM_LOG,
    SW_DM_NUM,
}SW_DEBUG_MODE;

typedef enum _SW_DEBUG_TOKEN
{
    SW_DTK_PATTERN,
    SW_DTK_LEVEL,
    SW_DTK_DATE,
    SW_DTK_TIME,
    SW_DTK_ERRNO,
    SW_DTK_CODE_FILE,
    SW_DTK_CODE_FUNC,
    SW_DTK_CODE_LINE,
    SW_DTK_EXTRA,
    SW_DTK_NUM
}SW_DEBUG_TOKEN;

typedef enum _SW_PRINTD_MODE
{
    SW_PRDM_NONE,
    SW_PRDM_SIMPLE,
    SW_PRDM_DETAIL,
    SW_PRDM_NUM
}SW_PRINTD_MODE;

#ifdef WIN32
#if !defined(__FUNCTION__)
#define __FUNCTION__ __func__
#endif
#endif

#if defined(WIN32) && !defined(__MINGW32__)
#define SW_PRINTD(format, ...) \
do \
{ \
	SW_DebugPrintd(SW_PRDM_DETAIL, __FILE__, __FUNCTION__, __LINE__, format, __VA_ARGS__); \
}while (0)

#define SW_PRINTDM(mode, format, ...) \
do \
{ \
	SW_DebugPrintd(mode, __FILE__, __FUNCTION__, __LINE__, format, __VA_ARGS__); \
}while (0)

#define SW_PRINTF(format, ...) \
do \
{ \
	SW_DebugPrintf(SW_DL_NONE, __FILE__, __FUNCTION__, __LINE__, SW_DS_DEFAULT, SW_DC_DEFAULT, SW_DC_DEFAULT, format, __VA_ARGS__); \
}while (0)

#define SW_PRINTP(style, foreColor, backColor, format, ...) \
do \
{ \
	SW_DebugPrintf(SW_DL_NONE, __FILE__, __FUNCTION__, __LINE__, style, foreColor, backColor, format, __VA_ARGS__); \
}while (0)

#define SW_ERR(format, ...) \
do \
{ \
	SW_DebugPrintf(SW_DL_ERR, __FILE__, __FUNCTION__, __LINE__, SW_DS_BRIGHT, SW_DC_RED, SW_DC_DEFAULT, format, __VA_ARGS__); \
}while (0)

#define SW_WRN(format, ...) \
do \
{ \
	SW_DebugPrintf(SW_DL_WRN, __FILE__, __FUNCTION__, __LINE__, SW_DS_BRIGHT, SW_DC_YELLOW, SW_DC_DEFAULT, format, __VA_ARGS__); \
}while (0)

#define SW_INF(format, ...) \
do \
{ \
	SW_DebugPrintf(SW_DL_INF, __FILE__, __FUNCTION__, __LINE__, SW_DS_BRIGHT, SW_DC_CYAN, SW_DC_DEFAULT, format, __VA_ARGS__); \
}while (0)

#define SW_DBG(format, ...) \
do \
{ \
	SW_DebugPrintf(SW_DL_DBG, __FILE__, __FUNCTION__, __LINE__, SW_DS_BRIGHT, SW_DC_GREEN, SW_DC_DEFAULT, format, __VA_ARGS__); \
}while (0)

#define SW_DEV(format, ...) \
do \
{ \
	SW_DebugPrintf(SW_DL_DEV, __FILE__, __FUNCTION__, __LINE__, SW_DS_BRIGHT, SW_DC_MAGENTA, SW_DC_DEFAULT, format, __VA_ARGS__); \
}while (0)
#else
#define SW_PRINTD(format, args...) \
do \
{ \
    SW_DebugPrintd(SW_PRDM_DETAIL, __FILE__, __FUNCTION__, __LINE__, format, ##args); \
}while (0)

#define SW_PRINTDM(mode, format, args...) \
do \
{ \
    SW_DebugPrintd(mode, __FILE__, __FUNCTION__, __LINE__, format, ##args); \
}while (0)

#define SW_PRINTF(format, args...) \
do \
{ \
    SW_DebugPrintf(SW_DL_NONE, __FILE__, __FUNCTION__, __LINE__, SW_DS_DEFAULT, SW_DC_DEFAULT, SW_DC_DEFAULT, format, ##args); \
}while (0)

#define SW_PRINTP(style, foreColor, backColor, format, args...) \
do \
{ \
    SW_DebugPrintf(SW_DL_NONE, __FILE__, __FUNCTION__, __LINE__, style, foreColor, backColor, format, ##args); \
}while (0)

#define SW_ERR(format, args...) \
do \
{ \
    SW_DebugPrintf(SW_DL_ERR, __FILE__, __FUNCTION__, __LINE__, SW_DS_BRIGHT, SW_DC_RED, SW_DC_DEFAULT, format, ##args); \
}while (0)

#define SW_WRN(format, args...) \
do \
{ \
    SW_DebugPrintf(SW_DL_WRN, __FILE__, __FUNCTION__, __LINE__, SW_DS_BRIGHT, SW_DC_YELLOW, SW_DC_DEFAULT, format, ##args); \
}while (0)

#define SW_INF(format, args...) \
do \
{ \
    SW_DebugPrintf(SW_DL_INF, __FILE__, __FUNCTION__, __LINE__, SW_DS_BRIGHT, SW_DC_CYAN, SW_DC_DEFAULT, format, ##args); \
}while (0)

#define SW_DBG(format, args...) \
do \
{ \
    SW_DebugPrintf(SW_DL_DBG, __FILE__, __FUNCTION__, __LINE__, SW_DS_BRIGHT, SW_DC_GREEN, SW_DC_DEFAULT, format, ##args); \
}while (0)

#define SW_DEV(format, args...) \
do \
{ \
    SW_DebugPrintf(SW_DL_DEV, __FILE__, __FUNCTION__, __LINE__, SW_DS_BRIGHT, SW_DC_MAGENTA, SW_DC_DEFAULT, format, ##args); \
}while (0)
#endif

SW_API SW_RET SW_InitDebugAPI(SW_VOID);
SW_API SW_RET SW_RunDebugAPI(SW_VOID);
SW_API SW_RET SW_StopDebugAPI(SW_VOID);
SW_API SW_RET SW_ExitDebugAPI(SW_VOID);
SW_API const SW_CHAR *SW_DebugLevelToStr(SW_DEBUG_LEVEL level);
SW_API SW_DEBUG_LEVEL SW_StrToDebugLevel(const SW_CHAR *pStr);
SW_API SW_RET SW_SetDebugLevel(SW_DEBUG_LEVEL level);
SW_API SW_DEBUG_LEVEL SW_GetDebugLevel(SW_VOID);
SW_API SW_RET SW_SetDebugFile(const SW_CHAR *pFileName);
SW_API SW_RET SW_GetDebugFile(SW_CHAR *pFileName, SW_UINT32 fileNameLen);
SW_API SW_RET SW_SetDebugMode(SW_UINT32 mode);
SW_API SW_UINT32 SW_GetDebugMode(SW_VOID);
SW_API SW_RET SW_EnableDebugToken(SW_DEBUG_LEVEL level, SW_DEBUG_TOKEN token, SW_BOOL enable);
SW_API SW_RET SW_IsDebugTokenEnabled(SW_DEBUG_LEVEL level, SW_DEBUG_TOKEN token);
SW_API SW_RET SW_EnableDebugTokenAllLevel(SW_DEBUG_TOKEN token, SW_BOOL enable);
SW_API SW_RET SW_EnableDebugPrintd(SW_BOOL enable);
SW_API SW_BOOL SW_IsDebugPrintdEnabled(SW_VOID);
SW_API SW_RET SW_DebugPrintf(SW_DEBUG_LEVEL level, const SW_CHAR *pCodeFileName
                             , const SW_CHAR *pCodeFuncName, SW_UINT32 codeLine
                             , SW_DEBUG_STYLE style, SW_DEBUG_COLOR foreColor
                             , SW_DEBUG_COLOR backColor, const SW_CHAR *pFormat, ...)
#ifdef WIN32
                             ;
#else
                             __THROW __attribute__ ((__format__ (__printf__, 8, 9)));
#endif
SW_API SW_RET SW_DebugPrintfFixedArg(SW_DEBUG_LEVEL level, const SW_CHAR *pCodeFileName, const SW_CHAR *pCodeFuncName
                                     , SW_UINT32 codeLine, SW_DEBUG_STYLE style, SW_DEBUG_COLOR foreColor
                                     , SW_DEBUG_COLOR backColor, const SW_CHAR *pExtra, FILE *pExtraFile
                                     , const SW_CHAR *pFormat, va_list ap);
SW_API SW_RET SW_DebugPrintd(SW_PRINTD_MODE mode, const SW_CHAR *pCodeFileName, const SW_CHAR *pCodeFuncName
                             , SW_UINT32 codeLine, const SW_CHAR *pFormat, ...)
#ifdef WIN32
                             ;
#else
                             __THROW __attribute__ ((__format__ (__printf__, 5, 6)));
#endif
SW_API SW_RET SW_PrintPatternFile(FILE *pFile, SW_DEBUG_STYLE style, SW_DEBUG_COLOR foreColor, SW_DEBUG_COLOR backColor);
SW_API SW_RET SW_RestorePatternFile(FILE *pFile);
SW_API SW_RET SW_PrintPattern(SW_DEBUG_STYLE style, SW_DEBUG_COLOR foreColor, SW_DEBUG_COLOR backColor);
SW_API SW_RET SW_RestorePattern(SW_VOID);
SW_API SW_RET SW_PrintPatternStrAnsi(SW_DEBUG_STYLE style, SW_DEBUG_COLOR foreColor, SW_DEBUG_COLOR backColor
                                     , SW_CHAR *pStr, SW_UINT32 strLen);
SW_API SW_RET SW_RestorePatternStrAnsi(SW_CHAR *pStr, SW_UINT32 strLen);
SW_API SW_RET SW_AnsiPrintf(const SW_CHAR *pFormat, ...)
#ifdef WIN32
                             ;
#else
                             __THROW __attribute__ ((__format__ (__printf__, 1, 2)));
#endif
SW_API SW_UINT32 SW_StrPrintf(SW_CHAR *pStr, SW_UINT32 strLen, const SW_CHAR *pFormat, ...)
#ifdef WIN32
                             ;
#else
                             __THROW __attribute__ ((__format__ (__printf__, 3, 4)));
#endif
SW_API SW_RET SW_PrintHex(const SW_VOID *pBuf, SW_UINT32 bufLen, SW_UINT32 bytesPerLine
                          , const SW_CHAR *pPrefix, const SW_CHAR *pSuffix);
SW_API SW_RET SW_PrintHexP(SW_DEBUG_STYLE style, SW_DEBUG_COLOR foreColor, SW_DEBUG_COLOR backColor
                           , const SW_VOID *pBuf, SW_UINT32 bufLen, SW_UINT32 bytesPerLine
                           , const SW_CHAR *pPrefix, const SW_CHAR *pSuffix);
#ifndef SW_V_DISABLE_CMDSERVER
SW_API SW_RET SW_CmdPrintd(SW_BOOL enable);
SW_API SW_RET SW_CmdSetDebugLevel(const SW_CHAR *pLevel);
#endif

#ifdef __cplusplus
}
#endif

#endif

